package com.wande.dataplatform.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wande.common.core.utils.StringUtils;
import com.wande.common.mybatis.core.page.PageQuery;
import com.wande.common.mybatis.core.page.TableDataInfo;
import com.wande.common.satoken.utils.LoginHelper;
import com.wande.dataplatform.domain.Screen;
import com.wande.dataplatform.domain.bo.ScreenBo;
import com.wande.dataplatform.domain.vo.ScreenVO;
import com.wande.dataplatform.mapper.ScreenMapper;
import com.wande.dataplatform.service.IScreenService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * 大屏设计Service业务层处理
 *
 * @author wande
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class ScreenServiceImpl implements IScreenService {

    private final ScreenMapper screenMapper;

    /**
     * 查询大屏设计列表
     */
    @Override
    public TableDataInfo<ScreenVO> queryPageList(ScreenBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<Screen> lqw = buildQueryWrapper(bo);
        Page<ScreenVO> result = screenMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询大屏设计列表
     */
    @Override
    public List<ScreenVO> queryList(ScreenBo bo) {
        LambdaQueryWrapper<Screen> lqw = buildQueryWrapper(bo);
        return screenMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Screen> buildQueryWrapper(ScreenBo bo) {
        LambdaQueryWrapper<Screen> lqw = Wrappers.lambdaQuery();
        lqw.eq(Screen::getTenantId, LoginHelper.getTenantId());
        lqw.like(StringUtils.isNotBlank(bo.getName()), Screen::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), Screen::getStatus, bo.getStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getScreenType()), Screen::getScreenType, bo.getScreenType());
        lqw.eq(bo.getProjectId() != null, Screen::getProjectId, bo.getProjectId());
        lqw.orderByDesc(Screen::getCreateTime);
        return lqw;
    }

    /**
     * 查询大屏设计详情
     */
    @Override
    public ScreenVO queryById(Long id) {
        return screenMapper.selectVoById(id);
    }

    /**
     * 新增大屏设计
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(ScreenBo bo) {
        Screen screen = BeanUtil.toBean(bo, Screen.class);
        screen.setTenantId(Long.valueOf(LoginHelper.getTenantId()));
        
        // 设置默认值
        if (screen.getStatus() == null) {
            screen.setStatus("DRAFT");
        }
        if (screen.getScreenType() == null) {
            screen.setScreenType("CUSTOM");
        }
        if (screen.getWidth() == null) {
            screen.setWidth(1920);
        }
        if (screen.getHeight() == null) {
            screen.setHeight(1080);
        }
        if (screen.getRefreshInterval() == null) {
            screen.setRefreshInterval(0);
        }
        
        // 生成预览URL
        String previewToken = IdUtil.simpleUUID();
        screen.setPreviewUrl("/screen/preview/" + previewToken);
        
        boolean flag = screenMapper.insert(screen) > 0;
        if (flag) {
            bo.setId(screen.getId());
        }
        return flag;
    }

    /**
     * 修改大屏设计
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(ScreenBo bo) {
        Screen screen = BeanUtil.toBean(bo, Screen.class);
        return screenMapper.updateById(screen) > 0;
    }

    /**
     * 删除大屏设计
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteByIds(List<Long> ids) {
        return screenMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 发布大屏
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean publishScreen(Long id) {
        Screen screen = screenMapper.selectById(id);
        if (screen == null) {
            throw new RuntimeException("大屏不存在");
        }
        
        // 生成发布URL
        String publishToken = IdUtil.simpleUUID();
        screen.setPublishUrl("/screen/view/" + publishToken);
        screen.setStatus("PUBLISHED");
        
        return screenMapper.updateById(screen) > 0;
    }

    /**
     * 下线大屏
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean offlineScreen(Long id) {
        Screen screen = screenMapper.selectById(id);
        if (screen == null) {
            throw new RuntimeException("大屏不存在");
        }
        
        screen.setStatus("OFFLINE");
        return screenMapper.updateById(screen) > 0;
    }

    /**
     * 获取预览URL
     */
    @Override
    public String getPreviewUrl(Long id) {
        Screen screen = screenMapper.selectById(id);
        if (screen == null) {
            throw new RuntimeException("大屏不存在");
        }
        return screen.getPreviewUrl();
    }

    /**
     * 查询大屏数据
     */
    @Override
    public Object queryScreenData(Long id, String componentId) {
        Screen screen = screenMapper.selectById(id);
        if (screen == null) {
            throw new RuntimeException("大屏不存在");
        }
        
        // 解析数据源配置
        if (StringUtils.isBlank(screen.getDatasourceConfig())) {
            return null;
        }
        
        try {
            JSONObject datasourceConfig = JSONUtil.parseObj(screen.getDatasourceConfig());
            JSONObject componentDataConfig = datasourceConfig.getJSONObject(componentId);
            
            if (componentDataConfig == null) {
                return null;
            }
            
            // 这里应该根据数据源配置查询实际数据
            // 简化实现，返回模拟数据
            log.info("查询大屏组件数据: screenId={}, componentId={}", id, componentId);
            
            // 实际应该调用数据查询服务
            return Map.of(
                "success", true,
                "data", List.of(),
                "message", "数据查询成功"
            );
        } catch (Exception e) {
            log.error("查询大屏数据失败", e);
            throw new RuntimeException("查询大屏数据失败: " + e.getMessage());
        }
    }
}
